from fastapi import APIRouter, Depends, HTTPException, Query
from typing import List, Optional, Dict

from app.core.deps import get_current_active_user
from app.models.models import User, Department
from app.schemas.department import DepartmentCreate, DepartmentUpdate, DepartmentOut
from app.schemas.base import ResponseBase, PageResponseBase, PageInfo

router = APIRouter()

@router.get("/", response_model=PageResponseBase[List[DepartmentOut]])
async def get_departments(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(10, ge=1, le=100, description="每页条数"),
    name: Optional[str] = Query(None, description="部门名称"),
    status: Optional[bool] = Query(None, description="状态"),
    _: User = Depends(get_current_active_user)
):
    """获取部门列表"""
    # 构建查询条件
    query = {}
    if name:
        query["name__contains"] = name
    if status is not None:
        query["status"] = status
    
    # 查询总数
    total = await Department.filter(**query).count()
    
    # 分页查询
    departments = await Department.filter(**query).offset((page - 1) * page_size).limit(page_size).all()
    
    # 构建部门列表
    department_list = []
    for department in departments:
        # 获取部门用户数量
        user_count = await User.filter(department_id=department.id).count()
        
        # 构建部门信息
        department_data = {
            "id": department.id,
            "name": department.name,
            "parent_id": department.parent_id,
            "sort": department.sort,
            "status": department.status,
            "user_count": user_count,
            "children": [],
            "created_at": department.created_at,
            "updated_at": department.updated_at
        }
        
        department_list.append(DepartmentOut(**department_data))
    
    # 构建分页信息
    page_info = PageInfo(page=page, page_size=page_size, total=total)
    
    return PageResponseBase[List[DepartmentOut]](
        data=department_list,
        page_info=page_info
    )

@router.get("/tree", response_model=ResponseBase[List[DepartmentOut]])
async def get_department_tree(
    status: Optional[bool] = Query(None, description="状态"),
    _: User = Depends(get_current_active_user)
):
    """获取部门树形结构"""
    # 构建查询条件
    query = {}
    if status is not None:
        query["status"] = status
    
    # 查询所有部门
    departments = await Department.filter(**query).all()
    
    # 构建部门字典
    department_dict: Dict[int, DepartmentOut] = {}
    for department in departments:
        # 获取部门用户数量
        user_count = await User.filter(department_id=department.id).count()
        
        # 构建部门信息
        department_data = {
            "id": department.id,
            "name": department.name,
            "parent_id": department.parent_id,
            "sort": department.sort,
            "status": department.status,
            "user_count": user_count,
            "children": [],
            "created_at": department.created_at,
            "updated_at": department.updated_at
        }
        
        department_dict[department.id] = DepartmentOut(**department_data)
    
    # 构建树形结构
    tree = []
    for department_id, department in department_dict.items():
        if department.parent_id is None:
            # 顶级部门
            tree.append(department)
        else:
            # 子部门
            if department.parent_id in department_dict:
                department_dict[department.parent_id].children.append(department)
    
    # 按排序字段排序
    tree.sort(key=lambda x: x.sort)
    for department in department_dict.values():
        department.children.sort(key=lambda x: x.sort)
    
    return ResponseBase[List[DepartmentOut]](data=tree)

@router.post("/", response_model=ResponseBase[DepartmentOut])
async def create_department(
    department_in: DepartmentCreate,
    _: User = Depends(get_current_active_user)
):
    """创建部门"""
    # 检查部门名称是否已存在
    if await Department.filter(name=department_in.name).exists():
        raise HTTPException(status_code=400, detail="部门名称已存在")
    
    # 检查父部门是否存在
    if department_in.parent_id and not await Department.filter(id=department_in.parent_id).exists():
        raise HTTPException(status_code=400, detail="父部门不存在")
    
    # 创建部门
    department = await Department.create(
        name=department_in.name,
        parent_id=department_in.parent_id,
        sort=department_in.sort,
        status=department_in.status
    )
    
    # 构建部门信息
    department_data = {
        "id": department.id,
        "name": department.name,
        "parent_id": department.parent_id,
        "sort": department.sort,
        "status": department.status,
        "user_count": 0,
        "children": [],
        "created_at": department.created_at,
        "updated_at": department.updated_at
    }
    
    return ResponseBase[DepartmentOut](data=DepartmentOut(**department_data))

@router.get("/{department_id}", response_model=ResponseBase[DepartmentOut])
async def get_department(
    department_id: int,
    _: User = Depends(get_current_active_user)
):
    """获取部门详情"""
    department = await Department.filter(id=department_id).first()
    if not department:
        raise HTTPException(status_code=404, detail="部门不存在")
    
    # 获取部门用户数量
    user_count = await User.filter(department_id=department.id).count()
    
    # 构建部门信息
    department_data = {
        "id": department.id,
        "name": department.name,
        "parent_id": department.parent_id,
        "sort": department.sort,
        "status": department.status,
        "user_count": user_count,
        "children": [],
        "created_at": department.created_at,
        "updated_at": department.updated_at
    }
    
    return ResponseBase[DepartmentOut](data=DepartmentOut(**department_data))

@router.put("/{department_id}", response_model=ResponseBase[DepartmentOut])
async def update_department(
    department_id: int,
    department_in: DepartmentUpdate,
    _: User = Depends(get_current_active_user)
):
    """更新部门"""
    department = await Department.filter(id=department_id).first()
    if not department:
        raise HTTPException(status_code=404, detail="部门不存在")
    
    # 检查部门名称是否已存在
    if department_in.name and department_in.name != department.name:
        if await Department.filter(name=department_in.name).exists():
            raise HTTPException(status_code=400, detail="部门名称已存在")
    
    # 检查父部门是否存在
    if department_in.parent_id and department_in.parent_id != department.parent_id:
        if not await Department.filter(id=department_in.parent_id).exists():
            raise HTTPException(status_code=400, detail="父部门不存在")
        
        # 检查是否将部门设置为自己的子部门
        if department_in.parent_id == department.id:
            raise HTTPException(status_code=400, detail="不能将部门设置为自己的子部门")
        
        # 检查是否将部门设置为自己的子部门的子部门
        child_ids = await get_child_department_ids(department.id)
        if department_in.parent_id in child_ids:
            raise HTTPException(status_code=400, detail="不能将部门设置为自己的子部门的子部门")
    
    # 更新部门信息
    update_data = department_in.dict(exclude_unset=True)
    
    # 更新部门
    await department.update_from_dict(update_data)
    await department.save()
    
    # 获取部门用户数量
    user_count = await User.filter(department_id=department.id).count()
    
    # 构建部门信息
    department_data = {
        "id": department.id,
        "name": department.name,
        "parent_id": department.parent_id,
        "sort": department.sort,
        "status": department.status,
        "user_count": user_count,
        "children": [],
        "created_at": department.created_at,
        "updated_at": department.updated_at
    }
    
    return ResponseBase[DepartmentOut](data=DepartmentOut(**department_data))

@router.delete("/{department_id}", response_model=ResponseBase)
async def delete_department(
    department_id: int,
    _: User = Depends(get_current_active_user)
):
    """删除部门"""
    department = await Department.filter(id=department_id).first()
    if not department:
        raise HTTPException(status_code=404, detail="部门不存在")
    
    # 检查部门是否有子部门
    if await Department.filter(parent_id=department.id).exists():
        raise HTTPException(status_code=400, detail="部门下有子部门，无法删除")
    
    # 检查部门是否有用户
    if await User.filter(department_id=department.id).exists():
        raise HTTPException(status_code=400, detail="部门下有用户，无法删除")
    
    # 删除部门
    await department.delete()
    
    return ResponseBase()

async def get_child_department_ids(department_id: int) -> List[int]:
    """获取子部门ID列表"""
    child_ids = []
    
    # 获取直接子部门
    children = await Department.filter(parent_id=department_id).all()
    for child in children:
        child_ids.append(child.id)
        # 递归获取子部门的子部门
        child_child_ids = await get_child_department_ids(child.id)
        child_ids.extend(child_child_ids)
    
    return child_ids